package cn.ai.shoes.client.utils;

import cn.ai.shoes.client.entity.ComfyuiModel;
import cn.ai.shoes.client.entity.ComfyuiUploadLog;
import cn.ai.shoes.client.entity.OssUploadLog;
import cn.ai.shoes.client.entity.vo.ComfyuiReturnVo;
import cn.ai.shoes.client.service.ComfyuiService;
import cn.ai.shoes.client.service.ComfyuiUploadService;
import cn.ai.shoes.client.service.FreemarkService;
import cn.ai.shoes.client.service.OssUploadLogService;
import cn.ai.shoes.common.core.mybatis.LambdaQueryWrapperX;
import cn.ai.shoes.common.exception.ServiceException;
import cn.ai.shoes.common.exception.constant.GlobalErrorCodeConstants;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.annotation.Resource;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

import static cn.ai.shoes.common.constant.GolbalConstants.MathConstants.RANDOM_MAX;
import static cn.ai.shoes.common.constant.GolbalConstants.MathConstants.RANDOM_MIN;

@Component
@Slf4j
public class ImageUtils {
    @Resource
    private OssUploadLogService ossUploadLogService;
    @Resource
    private ComfyuiUploadService comfyuiUploadService;
    @Resource
    private FreemarkService freemarkService;
    @Resource
    private ComfyuiService comfyuiService;

    /**
     * 检查并处理单个图片在ComfyUI服务器上的上传。
     * @param ossUploadLog     图片的OSS日志
     * @param currentServerUrl 当前ComfyUI服务器地址
     */
    public ComfyuiUploadLog handleImageUpload(OssUploadLog ossUploadLog, String currentServerUrl) {
        ComfyuiUploadLog newComfyuiUploadLog = new ComfyuiUploadLog();
        OssUploadLog originalOssUploadLog = null;
        String cfUploadIdsStr = ossUploadLog.getCfUploadIds();
        Integer originalId = ossUploadLog.getOriginalId();
        //判断originalId是否为空或者是否为0
        if (ObjectUtil.isNotEmpty(originalId) || originalId != 0) {
            // 如果originalId不为空，则检查图片是否已在当前服务器上传
            LambdaQueryWrapperX<OssUploadLog> eq = new LambdaQueryWrapperX<OssUploadLog>()
                   .eq(OssUploadLog::getId, originalId);
            originalOssUploadLog = ossUploadLogService.getOne(eq);
        }
        // 如果cfUploadIds不为空，则检查图片是否已在当前服务器上传
        if (StringUtil.isNotBlank(cfUploadIdsStr)) {
            List<Integer> comfyuiUploadIds = Arrays.stream(cfUploadIdsStr.split(","))
                    .filter(StringUtil::isNotBlank)
                    .map(Integer::parseInt)
                    .toList();
            // 只有在ID列表不为空时才查询数据库
            if (CollectionUtil.isNotEmpty(comfyuiUploadIds)) {
                LambdaQueryWrapperX<ComfyuiUploadLog> eq = new LambdaQueryWrapperX<ComfyuiUploadLog>()
                        .in(ComfyuiUploadLog::getId, comfyuiUploadIds)
                        .eq(ComfyuiUploadLog::getInUrl, true)
                        .eq(ComfyuiUploadLog::getIsSuccess, true)
                        .eq(ComfyuiUploadLog::getUrl, currentServerUrl);
                List<ComfyuiUploadLog> comfyuiUploadLogs = comfyuiUploadService.list(eq);
                if (CollectionUtil.isNotEmpty(comfyuiUploadLogs)) {
                    // 如果存在，则判断是否在当前服务器上传过
                    boolean existsOnCurrentServer = comfyuiUploadLogs.stream()
                            .anyMatch(log -> log.getUrl().contains(currentServerUrl));
                    if (!existsOnCurrentServer) {
                        // 如果不在当前服务器上传过，则上传到当前服务器
                        newComfyuiUploadLog = comfyuiUploadService.uploadImage(ossUploadLog, currentServerUrl,originalOssUploadLog);
                    }else {
                        // 如果在当前服务器上传过，则直接返回
                        newComfyuiUploadLog = comfyuiUploadLogs.get(0);
                        return newComfyuiUploadLog;
                    }
                } else {
                    // 如果数据库中没有记录，则上传到当前服务器
                    newComfyuiUploadLog = comfyuiUploadService.uploadImage(ossUploadLog, currentServerUrl,originalOssUploadLog);
                }
            }
        } else {
            // 如果cfUploadIds为空，说明从未上传过，直接上传
            newComfyuiUploadLog = comfyuiUploadService.uploadImage(ossUploadLog, currentServerUrl,originalOssUploadLog);
        }
        return newComfyuiUploadLog;
    }
    /**
     * 蒙版
     * @param vo
     * @return
     */
    @NotNull
    public static String maskStrUtil(String vo) {
        return "clipspace/" + vo + " [input]";
    }
    /**
     * 调用comfyui api接口生成任务
     * @param modelBean
     * @return
     */
    public ComfyuiReturnVo comfyuiImageUtil(ComfyuiModel modelBean, String templateName,String currentServerUrl) throws Exception {
        String promptId = createComfyuiTask(modelBean, templateName, currentServerUrl);
        HashMap historyResultBody = comfyuiService.waitingTask(promptId,currentServerUrl);
        // comfyuiServiceImpl.getViewUrlList(comfyuiServiceImpl.waitingTask(promptId), promptId)
        ComfyuiReturnVo comfyuiReturnVo = new ComfyuiReturnVo(promptId, comfyuiService.getViewUrlList(historyResultBody, promptId, currentServerUrl));
        return comfyuiReturnVo;
    }
    /**
     * 调用comfyui api接口生成任务
     * @return
     */
    public ComfyuiReturnVo comfyuiImageUtilV2(String pi,String currentServerUrl) throws Exception {
        HashMap historyResultBody = comfyuiService.waitingTask(pi,currentServerUrl);
        // comfyuiServiceImpl.getViewUrlList(comfyuiServiceImpl.waitingTask(promptId), promptId)
        ComfyuiReturnVo comfyuiReturnVo = new ComfyuiReturnVo(pi, comfyuiService.getViewUrlList(historyResultBody, pi, currentServerUrl));
        return comfyuiReturnVo;
    }
    /**
     * 调用comfyui api接口生成任务
     * @param modelBean
     * @return
     */
    public String createComfyuiTask(ComfyuiModel modelBean, String templateName, String currentServerUrl) throws Exception {
        JSONObject prompt = null;
        // 生成随机数，类似312923018761242
        modelBean.setSeed(generate15DigitRandomNumber());
        log.info("[ModelBean]:" + modelBean);
        prompt = freemarkService.renderImageTemp(modelBean, templateName);
        // 调用comfyui api接口生成任务
        String promptId = comfyuiService.generateTask(prompt, currentServerUrl);
        return promptId;
    }

    /**
     * 检查并处理单个图片在ComfyUI服务器上的上传。
     *
     * @param id   图片的OSS日志
     * @param type 当前ComfyUI服务器地址
     */
    public OssUploadLog selectOssUploadLogById(Integer id, String type) {
        OssUploadLog ossUploadLog = ossUploadLogService.getById(id);
        if (ObjectUtil.isEmpty(ossUploadLog)) {
            throw new ServiceException(GlobalErrorCodeConstants.IMAGE_NOT_FOUND.getCode(), type + "不存在, ID:" + id);
        }
        return ossUploadLog;
    }
    /**
     * 执行者
     *
     * @param
     * @return
     */
    public ComfyuiReturnVo getComfyuiReturnVo(String templateName, ComfyuiModel supplier,String currentServerUrl) throws Exception {
        return comfyuiImageUtil(supplier, templateName,currentServerUrl);
    }
    /**
     * 随机数
     *
     * @param v1
     * @return
     */

    public static double getRandom(Double v1) {
        double v2 = RANDOM_MIN + (RANDOM_MAX - RANDOM_MIN) * Math.random();
        return v1 + v2;
    }

    /**
     * 随机数
     *
     * @param v1
     * @return
     */
    public static float getRandom(Float v1) {
        float v2 = (float) (RANDOM_MIN + (RANDOM_MAX - RANDOM_MIN) * Math.random());
        return v1 + v2;
    }
    /**
     * 生成15位随机数字符串（基础版）
     * 注意：不适合对随机性要求高的场景
     */
    public static String generate15DigitRandomNumber() {
        // 生成10^14到10^15-1之间的随机数（15位）
        long min = 100000000000000L; // 10^14
        long max = 999999999999999L; // 10^15-1

        // Math.random()生成[0,1)的double，转换为目标范围内的long
        long randomNum = min + (long) (Math.random() * (max - min + 1));
        return java.lang.String.valueOf(randomNum);
    }
}
